package com.example.dormitorymanagement.service;

import com.example.dormitorymanagement.exception.BusinessException;
import com.example.dormitorymanagement.exception.ResourceNotFoundException;
import com.example.dormitorymanagement.model.*;
import com.example.dormitorymanagement.repository.OccupancyRepository;
import com.example.dormitorymanagement.repository.RoomRepository;
import com.example.dormitorymanagement.repository.StudentRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;

@Service
@RequiredArgsConstructor
public class OccupancyService {

    private final OccupancyRepository occupancyRepository;
    private final StudentRepository studentRepository;
    private final RoomRepository roomRepository;

    @Transactional
    public Occupancy checkIn(Integer studentId, Integer roomId) {
        Student student = studentRepository.findById(studentId)
                .orElseThrow(() -> new ResourceNotFoundException("学生不存在"));

        Room room = roomRepository.findById(roomId)
                .orElseThrow(() -> new ResourceNotFoundException("房间不存在"));

        // 检查学生是否已有活跃的入住记录
        if (occupancyRepository.findByStudentAndStatus(student, Occupancy.OccupancyStatus.ACTIVE).isPresent()) {
            throw new BusinessException("该学生已入住其他房间");
        }

        // 检查房间是否可用
        if (room.getStatus() != Room.RoomStatus.AVAILABLE) {
            throw new BusinessException("房间当前不可用");
        }

        // 检查房间容量
        long currentOccupancy = occupancyRepository.countByRoomAndStatus(room, Occupancy.OccupancyStatus.ACTIVE);
        if (currentOccupancy >= room.getCapacity()) {
            throw new BusinessException("房间已满");
        }

        // 创建入住记录
        Occupancy occupancy = new Occupancy(student, room, LocalDate.now());
        Occupancy savedOccupancy = occupancyRepository.save(occupancy);

        // 更新房间当前入住人数
        room.setCurrentOccupancy((int) (currentOccupancy + 1));
        if (room.getCurrentOccupancy() >= room.getCapacity()) {
            room.setStatus(Room.RoomStatus.FULL);
        }
        roomRepository.save(room);

        return savedOccupancy;
    }

    @Transactional
    public Occupancy checkOut(Integer occupancyId) {
        Occupancy occupancy = occupancyRepository.findById(occupancyId)
                .orElseThrow(() -> new ResourceNotFoundException("入住记录不存在"));

        if (occupancy.getStatus() == Occupancy.OccupancyStatus.INACTIVE) {
            throw new BusinessException("该入住记录已失效");
        }

        occupancy.setStatus(Occupancy.OccupancyStatus.INACTIVE);
        occupancy.setCheckOutDate(LocalDate.now());

        // 更新房间状态
        Room room = occupancy.getRoom();
        room.setCurrentOccupancy(room.getCurrentOccupancy() - 1);
        if (room.getStatus() == Room.RoomStatus.FULL) {
            room.setStatus(Room.RoomStatus.AVAILABLE);
        }
        roomRepository.save(room);

        return occupancyRepository.save(occupancy);
    }

    @Transactional(readOnly = true)
    public List<Occupancy> getOccupanciesByStudent(Integer studentId) {
        Student student = studentRepository.findById(studentId)
                .orElseThrow(() -> new ResourceNotFoundException("学生不存在"));
        return occupancyRepository.findByStudent(student);
    }

    @Transactional(readOnly = true)
    public List<Occupancy> getCurrentOccupanciesByRoom(Integer roomId) {
        Room room = roomRepository.findById(roomId)
                .orElseThrow(() -> new ResourceNotFoundException("房间不存在"));
        return occupancyRepository.findByRoomAndStatus(room, Occupancy.OccupancyStatus.ACTIVE);
    }

    @Transactional(readOnly = true)
    public Occupancy getCurrentOccupancyByStudent(Integer studentId) {
        Student student = studentRepository.findById(studentId)
                .orElseThrow(() -> new ResourceNotFoundException("学生不存在"));
        return occupancyRepository.findByStudentAndStatus(student, Occupancy.OccupancyStatus.ACTIVE)
                .orElseThrow(() -> new ResourceNotFoundException("该学生当前没有入住记录"));
    }
}